package com.changanw.dd.aspect;

import com.changanw.dd.annotation.DataSource;
import com.changanw.dd.datasource.DynamicDataSourceContextHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Aspect
@Order(9)
public class DataSourceAspect {
    /**
     * @annotation(com.changanw.dd.annotation.DataSource)   表示方法上有注解拦截下来
     * @within(com.changanw.dd.annotation.DataSource)  表示类上有这个注解的话，把类中的方法拦截下来
     */
    @Pointcut("@annotation(com.changanw.dd.annotation.DataSource) || @within(com.changanw.dd.annotation.DataSource)")
    public void pc(){

    }
    @Around("pc()")
    public Object around(ProceedingJoinPoint point) throws Throwable{
        //获取方法上的注解
        DataSource dataSource = getDataSource(point);
        if (dataSource != null){
            final String value = dataSource.value();
            DynamicDataSourceContextHolder.setDatasourceType(value);
        }
        try {
            return point.proceed();
        } catch (Throwable throwable) {
            //throwable.printStackTrace();
            throw throwable;
        }finally {
            DynamicDataSourceContextHolder.clearDataSource();
        }
    }

    private DataSource getDataSource(ProceedingJoinPoint point) {
        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        //查找方法上的注解
        DataSource annotation = AnnotationUtils.findAnnotation(methodSignature.getMethod(),DataSource.class);
        if (annotation != null){
            //说明方法上有DataSource注解
            return annotation;
        }
        return AnnotationUtils.findAnnotation(methodSignature.getDeclaringType(),DataSource.class);
    }
}
